package com.lagou.rpc.server;

import com.lagou.rpc.common.entity.RPCRequestData;
import com.lagou.rpc.common.handler.RequestHandlerRegistry;
import com.lagou.rpc.common.handler.SimpleRpcProtocolDecoder;
import com.lagou.rpc.common.handler.SimpleRpcProtocolEncoder;
import com.lagou.rpc.common.handler.SimpleRpcTransferDataHandler;
import com.lagou.rpc.server.handler.RPCRequestDataRequestHandler;
import com.lagou.rpc.common.entity.ServerGetRequest;
import com.lagou.rpc.server.handler.ServerGetRequestHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 服务端socket监听处理逻辑
 *
 * @author wlz
 * @date 2020/4/29
 */
public class SimpleRpcEndPoint {

    private static final Logger logger = LoggerFactory.getLogger(SimpleRpcEndPoint.class);

    private SimpleRpcMethodRegistry simpleRpcMethodRegistry;

    private RequestHandlerRegistry requestHandlerRegistry;

    private ServerBootstrap serverBootstrap;

    private NioEventLoopGroup masterLoop;

    private NioEventLoopGroup workerLoop;

    private SimpleRpcConfig simpleRpcConfig;

    public SimpleRpcEndPoint(SimpleRpcMethodRegistry simpleRpcMethodRegistry, SimpleRpcConfig simpleRpcConfig) {
        this.simpleRpcMethodRegistry = simpleRpcMethodRegistry;
        this.requestHandlerRegistry = new RequestHandlerRegistry();
        serverBootstrap = new ServerBootstrap();
        this.simpleRpcConfig = simpleRpcConfig;
        // 创建master工作线程池
        masterLoop = new NioEventLoopGroup(simpleRpcConfig.getMasterThreadPoolSize());
        // 创建worker工作线程池
        workerLoop = new NioEventLoopGroup(simpleRpcConfig.getWorkerThreadPoolSize());
    }

    public void start(int port) {
        //  注册请求处理器
        requestHandlerRegistry.register(ServerGetRequest.class, new ServerGetRequestHandler(simpleRpcMethodRegistry));
        requestHandlerRegistry.register(RPCRequestData.class, new RPCRequestDataRequestHandler(simpleRpcMethodRegistry,
                simpleRpcConfig.getConverter()));
        // 开启netty服务
        try {
            serverBootstrap.group(masterLoop, workerLoop)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel channel) throws Exception {
                            channel.pipeline()
                                    // 协议处理，将请求数据转换为transferData
                                    .addLast(new SimpleRpcProtocolDecoder())
                                    // response编码
                                    .addLast(new SimpleRpcProtocolEncoder())
                                    // 处理请求rpc逻辑
                                    .addLast(new SimpleRpcTransferDataHandler(simpleRpcConfig.getConverter(), requestHandlerRegistry));
                        }
                    }).bind(port).sync();
            logger.info("netty server for rpc started at " + port);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
